package main

import (
	"fmt"
	"reflect"
)

/*
   Go 语言在 reflect 包里定义了各种类型，实现了反射的各种函数，通过它们可以在运行时检测类型的信息、改变类型的值。


	Go语言的类型：

		变量包括（type, value）两部分,理解这一点就知道为什么nil != nil了

		type 包括 static type和concrete type.
			static type是在编码是看见的类型(如int、string)，
        	concrete type是runtime系统看见的类型

		类型断言能否成功，取决于变量的concrete type，而不是static type。
			因此，一个 reader变量如果它的concrete type也实现了write方法的话，它也可以被类型断言为writer。

		静态类型:
			type MyInt int // int 就是静态类型

		动态类型:
			var A interface{}
			A = 10  // 静态类型为interface{}  动态为int

		在Golang的实现中，每个interface变量都有一个对应pair，pair中记录了实际变量的值和类型:
			(value, type)

		value是实际变量值，type是实际变量的类型。一个interface{}类型的变量包含了2个指针，一个指针指向值的类型【对应concrete type】，
		另外一个指针指向实际的值【对应value】。

	Type和Value:
		reflect.TypeOf()是获取pair中的type，reflect.ValueOf()获取pair中的value。




*/
func main() {

	var x float64 = 3.4

	fmt.Println("type: ", reflect.TypeOf(x))
	fmt.Println("value: ", reflect.ValueOf(x))

	fmt.Println("-------------------")

	// 根据反射的值，来获取对应的类型和数值
	v :=reflect.ValueOf(x)
	fmt.Println("kind is float64: ",v.Kind() == reflect.Float64)
	fmt.Println("type : ",v.Type())
	fmt.Println("value : ",v.Float())


}
